<template>
  <ToolLayout>
    <!-- 工具栏slot -->
    <template #toolbar>
      <Toolbar>
        <div class="flex items-center space-x-6">
          <div>
            <h1 class="text-2xl font-bold text-gray-800 flex items-center">
              <i class="fas fa-sitemap text-blue-500 mr-3"></i>
              思维导图转换器
            </h1>
            <p class="text-sm text-gray-600 mt-1">
              将您的 Markdown 文档转换为交互式思维导图
            </p>
          </div>
        </div>
        <div class="flex items-center space-x-3">
          <button @click="loadTemplate" class="flex items-center px-3 py-2 text-sm bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors">
            <i class="fas fa-file-import mr-2"></i>加载模板
          </button>
          <button @click="clearContent" class="flex items-center px-3 py-2 text-sm bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors">
            <i class="fas fa-eraser mr-2"></i>清空内容
          </button>
          <button @click="fitToView" class="flex items-center px-3 py-2 text-sm bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors">
            <i class="fas fa-compress-arrows-alt mr-2"></i>适应视图
          </button>
          
          <!-- 导出下拉菜单 -->
          <div class="relative" ref="exportDropdown">
            <button 
              @click="toggleExportMenu" 
              class="flex items-center px-3 py-2 text-sm bg-purple-500 text-white rounded-lg hover:bg-purple-600 transition-colors"
            >
              <i class="fas fa-download mr-2"></i>导出
              <i class="fas fa-chevron-down ml-2 text-xs"></i>
            </button>
            <div 
              v-show="showExportMenu"
              class="absolute right-0 top-full mt-2 w-40 bg-white border border-gray-200 rounded-lg shadow-lg z-50"
            >
              <button @click="exportSVG" class="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center">
                <i class="fas fa-vector-square mr-2 text-green-500"></i>导出 SVG
              </button>
              <button @click="exportPNG" class="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center">
                <i class="fas fa-image mr-2 text-blue-500"></i>导出 PNG
              </button>
              <button @click="exportJPG" class="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 flex items-center">
                <i class="fas fa-image mr-2 text-orange-500"></i>导出 JPG
              </button>
            </div>
          </div>
        </div>
      </Toolbar>
    </template>
    
    <!-- 输入区slot -->
    <template #input>
      <InputPanel>
        <div class="flex flex-col h-full">
          <div class="bg-gray-50 px-6 py-4 border-b border-gray-200">
            <h3 class="text-lg font-semibold text-gray-800 flex items-center">
              <i class="fab fa-markdown text-blue-500 mr-2"></i>
              Markdown 编辑器
            </h3>
          </div>
          <div class="flex-1 p-0">
            <textarea
              v-model="markdownContent"
              @input="debounceUpdate"
              class="w-full h-full p-6 border-0 resize-none focus:outline-none font-mono text-sm"
              placeholder="请输入您的 Markdown 内容..."
            ></textarea>
          </div>
          <div class="bg-gray-50 px-6 py-3 border-t border-gray-200">
            <div class="flex items-center justify-between text-sm text-gray-500">
              <span>字符数：{{ markdownContent.length }}</span>
              <span>行数：{{ lineCount }}</span>
            </div>
          </div>
        </div>
      </InputPanel>
    </template>
    
    <!-- 展示区slot -->
    <template #output>
      <OutputPanel>
        <div class="flex flex-col h-full">
          <div class="bg-gray-50 px-6 py-4 border-b border-gray-200 flex items-center justify-between">
            <h3 class="text-lg font-semibold text-gray-800 flex items-center">
              <i class="fas fa-eye text-green-500 mr-2"></i>
              思维导图预览
            </h3>
            <div class="flex items-center space-x-2">
              <div class="flex items-center space-x-2 bg-gray-100 rounded-lg p-2">
                <span class="text-sm text-gray-600">缩放:</span>
                <button @click="zoomOut" class="p-1 hover:bg-gray-200 rounded"><i class="fas fa-minus text-sm"></i></button>
                <span class="text-sm min-w-12 text-center">{{ Math.round(currentZoom * 100) }}%</span>
                <button @click="zoomIn" class="p-1 hover:bg-gray-200 rounded"><i class="fas fa-plus text-sm"></i></button>
                <button @click="resetZoom" class="p-1 hover:bg-gray-200 rounded"><i class="fas fa-home text-sm"></i></button>
              </div>
              <button @click="fitToView" class="px-3 py-1 text-sm bg-gray-200 hover:bg-gray-300 rounded transition-colors">
                <i class="fas fa-compress-arrows-alt mr-1"></i>适应视图
              </button>
              <button @click="toggleFullscreen" class="px-3 py-1 text-sm bg-gray-200 hover:bg-gray-300 rounded transition-colors">
                <i class="fas fa-expand mr-1"></i>全屏
              </button>
            </div>
          </div>
          <div class="flex-1 relative overflow-hidden">
            <div ref="mindmapContainer" class="w-full h-full" style="background-color: #fafafa;">
              <div v-if="!markdownContent.trim()" class="flex items-center justify-center h-full text-gray-400">
                <div class="text-center">
                  <i class="fas fa-sitemap text-4xl mb-4"></i>
                  <p>请在左侧输入 Markdown 内容</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </OutputPanel>
    </template>
    
    <!-- 底部提示slot -->
    <template #footer>
      <FooterTip>
        <div class="bg-blue-50 rounded-xl p-6">
          <h3 class="text-lg font-semibold text-blue-800 mb-4">
            <i class="fas fa-info-circle mr-2"></i>
            使用说明
          </h3>
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-blue-700">
            <div>
              <h4 class="font-medium mb-2">支持的 Markdown 语法：</h4>
              <ul class="space-y-1 text-sm">
                <li>• # 一级标题（主节点）</li>
                <li>• ## 二级标题（子节点）</li>
                <li>• ### 三级标题（叶子节点）</li>
                <li>• 支持多层级嵌套</li>
                <li>• 支持列表项作为节点</li>
              </ul>
            </div>
            <div>
              <h4 class="font-medium mb-2">交互功能：</h4>
              <ul class="space-y-1 text-sm">
                <li>• 点击节点可折叠/展开</li>
                <li>• 鼠标滚轮缩放查看</li>
                <li>• 拖拽移动视图位置</li>
                <li>• 支持多种格式导出</li>
                <li>• 实时预览更新</li>
              </ul>
            </div>
          </div>
        </div>
      </FooterTip>
    </template>
  </ToolLayout>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import ToolLayout from '../../layouts/ToolLayout.vue';
import Toolbar from '../../components/common/Toolbar.vue';
import InputPanel from '../../components/common/InputPanel.vue';
import OutputPanel from '../../components/common/OutputPanel.vue';
import FooterTip from '../../components/common/FooterTip.vue';

// 响应式数据
const markdownContent = ref('')
const mindmapContainer = ref<HTMLElement | null>(null)
const currentZoom = ref(1)
const showExportMenu = ref(false)
const exportDropdown = ref<HTMLElement | null>(null)

// Markmap 相关变量
let markmap: any = null
let markmapSvg: any = null
let updateTimeout: number | null = null

// 计算属性
const lineCount = computed(() => {
  return markdownContent.value.split('\n').length
})

// 防抖更新函数
function debounceUpdate() {
  if (updateTimeout) {
    clearTimeout(updateTimeout)
  }
  updateTimeout = setTimeout(() => {
    updateMindmap()
  }, 300) as unknown as number
}

// 切换导出菜单
function toggleExportMenu() {
  showExportMenu.value = !showExportMenu.value
}

// 点击外部关闭菜单
function handleClickOutside(event: MouseEvent) {
  if (exportDropdown.value && !exportDropdown.value.contains(event.target as Node)) {
    showExportMenu.value = false
  }
}

// 方法
function loadTemplate() {
  markdownContent.value = `# 产品开发流程
## 需求分析
### 用户调研
#### 问卷调查
#### 用户访谈
#### 焦点小组
### 竞品分析
#### 功能对比
#### 价格分析
#### 用户体验
### 需求文档
#### 功能需求
#### 非功能需求
#### 约束条件
## 设计阶段
### UI 设计
#### 视觉设计
#### 交互设计
#### 设计规范
### 原型制作
#### 低保真原型
#### 高保真原型
#### 交互原型
## 开发阶段
### 前端开发
#### 页面开发
#### 组件开发
#### 样式优化
### 后端开发
#### API 开发
#### 数据库设计
#### 性能优化
### 测试
#### 单元测试
#### 集成测试
#### 用户测试
## 发布阶段
### 内测
#### Alpha 测试
#### Bug 修复
### 公测
#### Beta 测试
#### 用户反馈
### 正式发布
#### 部署上线
#### 监控运维`
  updateMindmap()
}

function clearContent() {
  markdownContent.value = ''
  if (mindmapContainer.value) {
    mindmapContainer.value.innerHTML = ''
  }
  markmap = null
  markmapSvg = null
}

async function updateMindmap() {
  if (!markdownContent.value.trim() || !mindmapContainer.value) {
    return
  }

  try {
    // 动态导入 markmap 库
    const { Transformer } = await import('markmap-lib')
    const { Markmap, loadCSS, loadJS } = await import('markmap-view')
    
    // 创建 transformer
    const transformer = new Transformer()
    
    // 转换 markdown 为 markmap 数据
    const { root, features } = transformer.transform(markdownContent.value)
    
    // 如果容器没有 SVG，则创建
    if (!markmapSvg) {
      // 清空容器
      mindmapContainer.value.innerHTML = ''
      
      // 创建 SVG 元素
      markmapSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
      markmapSvg.style.width = '100%'
      markmapSvg.style.height = '100%'
      mindmapContainer.value.appendChild(markmapSvg)
      
      // 创建 Markmap 实例
      markmap = Markmap.create(markmapSvg, {
        duration: 500,
        maxWidth: 300,
        spacingVertical: 5,
        spacingHorizontal: 80,
        autoFit: true,
        pan: true,
        zoom: true
      })
    }
    
    // 加载必要的资源
    const { styles, scripts } = transformer.getUsedAssets(features)
    if (styles) loadCSS(styles)
    if (scripts) loadJS(scripts, { getMarkmap: () => markmap })
    
    // 渲染思维导图
    markmap.setData(root)
    markmap.fit()
    
  } catch (error) {
    console.error('渲染思维导图失败:', error)
    if (mindmapContainer.value) {
      mindmapContainer.value.innerHTML = `
        <div class="flex items-center justify-center h-full text-red-400">
          <div class="text-center">
            <i class="fas fa-exclamation-triangle text-4xl mb-4"></i>
            <p>思维导图渲染失败</p>
            <p class="text-sm mt-2">请检查 Markdown 格式</p>
          </div>
        </div>
      `
    }
  }
}

function zoomIn() {
  if (markmap) {
    markmap.rescale(1.25)
    currentZoom.value = Math.min(currentZoom.value * 1.25, 3)
  }
}

function zoomOut() {
  if (markmap) {
    markmap.rescale(0.8)
    currentZoom.value = Math.max(currentZoom.value * 0.8, 0.3)
  }
}

function resetZoom() {
  if (markmap) {
    markmap.fit()
    currentZoom.value = 1
  }
}

function fitToView() {
  if (markmap) {
    markmap.fit()
    currentZoom.value = 1
  }
}

function exportSVG() {
  showExportMenu.value = false
  if (markmapSvg) {
    const svgData = new XMLSerializer().serializeToString(markmapSvg)
    const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' })
    const url = URL.createObjectURL(svgBlob)
    
    const link = document.createElement('a')
    link.href = url
    link.download = 'mindmap.svg'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    URL.revokeObjectURL(url)
  }
}

// 导出PNG（优先SVG转Canvas，兜底用html2canvas）
async function exportPNG() {
  showExportMenu.value = false
  if (!markmapSvg) return
  try {
    await svgToImageExport('png')
  } catch (e) {
    // 兜底方案
    await html2canvasExport('png')
  }
}

// 导出JPG（优先SVG转Canvas，兜底用html2canvas）
async function exportJPG() {
  showExportMenu.value = false
  if (!markmapSvg) return
  try {
    await svgToImageExport('jpg')
  } catch (e) {
    // 兜底方案
    await html2canvasExport('jpg')
  }
}

// SVG转图片主流程（按照官方文档最佳实践）
async function svgToImageExport(format: 'png' | 'jpg') {
  if (!markmapSvg) throw new Error('no svg')

  // 1. 导出前自动适应视图，确保内容全部可见
  fitToView();
  await nextTick();

  // 2. 获取SVG内容边界，动态调整SVG尺寸
  const svgElement = markmapSvg as SVGSVGElement
  // 记录原始尺寸
  const origWidth = svgElement.getAttribute('width');
  const origHeight = svgElement.getAttribute('height');
  const origViewBox = svgElement.getAttribute('viewBox');

  // 获取内容边界
  const bbox = svgElement.getBBox();
  const padding = 40;
  const svgWidth = bbox.width + padding * 2;
  const svgHeight = bbox.height + padding * 2;
  svgElement.setAttribute('width', svgWidth + 'px');
  svgElement.setAttribute('height', svgHeight + 'px');
  svgElement.setAttribute('viewBox', `${bbox.x - padding} ${bbox.y - padding} ${svgWidth} ${svgHeight}`);

  // 3. 设置高分辨率参数
  const scaleFactor = 8 // 极致高清
  const canvasWidth = svgWidth * scaleFactor
  const canvasHeight = svgHeight * scaleFactor

  // 4. 创建高分辨率Canvas
  const canvas = document.createElement('canvas')
  canvas.width = canvasWidth
  canvas.height = canvasHeight

  const ctx = canvas.getContext('2d')!
  ctx.imageSmoothingEnabled = true
  ctx.imageSmoothingQuality = 'high'

  // 5. 设置背景色
  ctx.fillStyle = format === 'jpg' ? '#ffffff' : '#fafafa'
  ctx.fillRect(0, 0, canvasWidth, canvasHeight)

  // 6. 获取并优化SVG数据
  const svgData = new XMLSerializer().serializeToString(svgElement)

  // 确保SVG有明确的尺寸属性
  const optimizedSvgData = svgData
    .replace(/<svg([^>]*)>/, (match, attrs) => {
      // 移除现有的width/height属性，添加明确的像素尺寸
      const cleanAttrs = attrs.replace(/\s*(width|height)="[^"]*"/g, '')
      return `<svg${cleanAttrs} width="${svgWidth}px" height="${svgHeight}px">`
    })
    .replace(/font-family="[^"]*"/g, 'font-family="system-ui, -apple-system, BlinkMacSystemFont, sans-serif"')

  // 7. 创建优化的SVG Blob
  const svgBlob = new Blob([optimizedSvgData], { 
    type: 'image/svg+xml;charset=utf-8' 
  })

  // 8. 转换为图片并绘制到Canvas
  return new Promise<void>((resolve, reject) => {
    const img = new Image()

    img.onload = () => {
      try {
        // 按比例绘制到高分辨率Canvas
        ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight)

        // 导出图片
        const mimeType = format === 'jpg' ? 'image/jpeg' : 'image/png'
        const quality = format === 'jpg' ? 1 : undefined // 极致高清

        canvas.toBlob((blob) => {
          // 导出后还原SVG尺寸
          if (origWidth) svgElement.setAttribute('width', origWidth);
          if (origHeight) svgElement.setAttribute('height', origHeight);
          if (origViewBox) svgElement.setAttribute('viewBox', origViewBox);

          if (blob) {
            const imageUrl = URL.createObjectURL(blob)
            const link = document.createElement('a')
            link.href = imageUrl
            link.download = `mindmap.${format}`
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link)
            URL.revokeObjectURL(imageUrl)
            resolve()
          } else {
            reject(new Error('Failed to create blob'))
          }
        }, mimeType, quality)
      } catch (error) {
        // 导出后还原SVG尺寸
        if (origWidth) svgElement.setAttribute('width', origWidth);
        if (origHeight) svgElement.setAttribute('height', origHeight);
        if (origViewBox) svgElement.setAttribute('viewBox', origViewBox);
        reject(error)
      }
    }

    img.onerror = (error) => {
      // 导出后还原SVG尺寸
      if (origWidth) svgElement.setAttribute('width', origWidth);
      if (origHeight) svgElement.setAttribute('height', origHeight);
      if (origViewBox) svgElement.setAttribute('viewBox', origViewBox);
      console.error('Image load error:', error)
      reject(new Error('Failed to load SVG as image'))
    }

    // 使用data URL避免跨域问题
    const reader = new FileReader()
    reader.onload = () => {
      img.src = reader.result as string
    }
    reader.onerror = () => {
      // 导出后还原SVG尺寸
      if (origWidth) svgElement.setAttribute('width', origWidth);
      if (origHeight) svgElement.setAttribute('height', origHeight);
      if (origViewBox) svgElement.setAttribute('viewBox', origViewBox);
      reject(new Error('Failed to read SVG blob'))
    }
    reader.readAsDataURL(svgBlob)
  })
}

// html2canvas 兜底方案
async function html2canvasExport(format: 'png' | 'jpg') {
  if (!mindmapContainer.value) return

  try {
    // 动态导入html2canvas (使用类型断言解决TS问题)
    const html2canvas = (await import('html2canvas' as any)).default as any

    // 导出前自动适应视图，确保内容全部可见
    fitToView();
    await nextTick();

    // 获取容器尺寸
    const containerRect = mindmapContainer.value.getBoundingClientRect()

    // 使用html2canvas截图
    const canvas = await html2canvas(mindmapContainer.value, {
      allowTaint: true,
      useCORS: true,
      scale: 6, // 极致高清
      width: containerRect.width,
      height: containerRect.height,
      backgroundColor: format === 'jpg' ? '#ffffff' : '#fafafa',
      logging: false,
      imageTimeout: 15000,
      removeContainer: false,
      foreignObjectRendering: true,
      // 确保SVG内容被正确渲染
      ignoreElements: (element) => {
        // 跳过一些可能导致问题的元素
        return element.tagName === 'SCRIPT' || element.tagName === 'STYLE'
      }
    })

    // 导出图片
    return new Promise<void>((resolve, reject) => {
      const mimeType = format === 'jpg' ? 'image/jpeg' : 'image/png'
      const quality = format === 'jpg' ? 1 : undefined // 极致高清

      canvas.toBlob((blob) => {
        if (blob) {
          const url = URL.createObjectURL(blob)
          const link = document.createElement('a')
          link.href = url
          link.download = `mindmap.${format}`
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          URL.revokeObjectURL(url)
          resolve()
        } else {
          reject(new Error('Failed to create blob from canvas'))
        }
      }, mimeType, quality)
    })
  } catch (error) {
    console.error('html2canvas export failed:', error)
    throw error
  }
}

function toggleFullscreen() {
  if (document.fullscreenElement) {
    document.exitFullscreen()
  } else {
    document.documentElement.requestFullscreen()
  }
}

// 生命周期
onMounted(async () => {
  await nextTick()
  if (markdownContent.value.trim()) {
    updateMindmap()
  }
  
  // 添加全局点击事件监听
  document.addEventListener('click', handleClickOutside)
})

onUnmounted(() => {
  if (updateTimeout) {
    clearTimeout(updateTimeout)
  }
  document.removeEventListener('click', handleClickOutside)
})
</script>

<style scoped>
textarea {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

/* 思维导图样式优化 */
:deep(.markmap-node) {
  cursor: pointer;
}

:deep(.markmap-foreign) {
  font-family: 'system-ui', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', sans-serif;
}
</style> 